﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Threading;

namespace mediaPrime.Controls
{
    public class MPMenu : ListBox
    {
        public static readonly RoutedCommand MPMenuItemClickCommand = new RoutedCommand();

        public delegate void MPMenuItemClickedEventHandler(object sender, MPMenuItemClickedEventArgs e);

        public event MPMenuItemClickedEventHandler MenuItemClicked;

        static MPMenu()
        {
            // Use another default style than the base class
            FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
                typeof(MPMenu), new FrameworkPropertyMetadata(typeof(MPMenu))
            );
        }

        public MPMenu()
        {
            var mpMenuItemClickCommandBinding = new CommandBinding(MPMenuItemClickCommand);
            mpMenuItemClickCommandBinding.CanExecute += mpMenuItemClickCommandBinding_CanExecute;
            mpMenuItemClickCommandBinding.Executed += mpMenuItemClickCommandBinding_Executed;

            CommandBindings.Add(mpMenuItemClickCommandBinding);

            this.Loaded += MPMenu_Loaded;
        
        }

        private void MPMenu_Loaded(object sender, RoutedEventArgs e)
        {
            var traversalRequest = new TraversalRequest(FocusNavigationDirection.Next);
            MoveFocus(traversalRequest);
        }

        private void mpMenuItemClickCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var menuItemClicked = MenuItemClicked;
            if (menuItemClicked != null)
                menuItemClicked(sender, new MPMenuItemClickedEventArgs() { Item = e.Parameter });
        }

        private void mpMenuItemClickCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (e.OriginalSource is MPTileButton)
                e.CanExecute = (e.OriginalSource as MPTileButton).IsEnabled;
            else
                e.CanExecute = true;
        }

        protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
        {
            base.OnItemsSourceChanged(oldValue, newValue);
            this.Dispatcher.BeginInvoke((Action)delegate
            {
                var traversalRequest = new TraversalRequest(FocusNavigationDirection.Previous);
                MoveFocus(traversalRequest);
            }, DispatcherPriority.Render);
        }


      
        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            if (e.Key == Key.Right)
            {
                e.Handled = true;
                var traversalRequest = new TraversalRequest(FocusNavigationDirection.Right);
                MoveFocus(traversalRequest);
            }
            else if (e.Key == Key.Left)
            {
                e.Handled = true;
                var traversalRequest = new TraversalRequest(FocusNavigationDirection.Left);
                MoveFocus(traversalRequest);
            }

            base.OnPreviewKeyDown(e);
        }

    }

    public class MPMenuItemClickedEventArgs : EventArgs
    {
        public object Item { get; set; }
    }

    public class MPMenuItemBase
    {

    }
    public class MPMenuItem : MPMenuItemBase
    {
        public bool IsEnabled { get; set; }

        public string Content { get; set; }

        public object Tag { get; set; }

        public MPMenuItem()
            : this(null, true)
        {
        }

        public MPMenuItem(string content)
            : this(content, true)
        {

        }

        public MPMenuItem(string content, bool isEnabled)
        {
            Content = content;
            IsEnabled = isEnabled;
        }

        public override string ToString()
        {
            return Content;
        }
    }

    public class MPMenuItemSeparator : MPMenuItemBase
    {
        // No code
    }

    public class MPMenuHeaderItem : MPMenuItemBase
    {
        public string Header { get; set; }

        public MPMenuHeaderItem(string header)
        {
            Header = header;
        }

        public override string ToString()
        {
            return Header;
        }
    }

    public class MPMenuItemTemplateSelector : DataTemplateSelector
    {
        public DataTemplate Default { get; set; }
        public DataTemplate Header { get; set; }
        public DataTemplate Separator { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item is MPMenuItem)
                return Default;
            else if (item is MPMenuHeaderItem)
                return Header;
            else if (item is MPMenuItemSeparator)
                return Separator;

            return base.SelectTemplate(item, container);
        }
    }

    public class MPMenuItemStyleSelector : StyleSelector
    {
        public Style Default { get; set; }
        public Style Separator { get; set; }
        public Style Header { get; set; }
        public override Style SelectStyle(object item, DependencyObject container)
        {
            if (item is MPMenuItemSeparator)
                return Separator;
            else if (item is MPMenuHeaderItem)
                return Header;
            else
                return Default;
        }
    }
}
